from django.db import models
# from fontTools.ufoLib.utils import deprecated

from common.snowflake import Snowflake


class Serial(models.Model):
    """
    序列号模型
    TODO
    我们需要增加一个序列号转换的数字
    """
    id = models.BigIntegerField(primary_key=True, default=Snowflake.generate, verbose_name="主键")
    serial = models.CharField(max_length=128, null=True, blank=True, verbose_name="序列号")
    serial_active_count = models.IntegerField(blank=True, null=True, verbose_name="激活次数")
    reseller_id = models.BigIntegerField(blank=True, null=True, verbose_name="经销商ID")
    reseller_name = models.CharField(max_length=50, null=True, blank=True, verbose_name="经销商")
    shop_id = models.BigIntegerField(blank=True, null=True, verbose_name="店铺ID")
    shop_name = models.CharField(max_length=50, blank=True, null=True, verbose_name="店铺名")
    batch_id = models.BigIntegerField(blank=True, null=True, verbose_name="批次ID")
    batch_name = models.CharField(max_length=50, null=True, blank=True, verbose_name="所属批次")
    account_id = models.BigIntegerField(blank=True, null=True, verbose_name="账号ID")
    account_name = models.CharField(max_length=50, null=True, blank=True, verbose_name="客户名称")
    device_id = models.BigIntegerField(blank=True, null=True, verbose_name="设备ID",help_text="激活后将会与某个设备进行关联")
    machine_code = models.CharField(max_length=255, null=True, blank=True, verbose_name="机器码")
    status = models.IntegerField(blank=True, null=True, verbose_name="序列号状态")
    update_time = models.DateTimeField(blank=True, null=True, verbose_name="更新时间")
    serial_valid_days = models.IntegerField(blank=True, null=True, verbose_name="有效天数")

    class Meta:
        db_table = 'fe_serial'
        verbose_name = '序列号'
        verbose_name_plural = '序列号'
        abstract = True
        managed = False

    # 获取表名
    @classmethod
    def get_table_name(cls, suffix: int):
        if 0 <= suffix < 128:
            print("serial分表:", suffix)
            return 'fe_serial_%d' % suffix
        suffix = abs(hash(str(suffix))) % 128
        print("serial分表:", suffix)
        return 'fe_serial_%d' % suffix

    # 缓存
    _table_model = {}

    # 根据后缀获取表模型
    @classmethod
    def sharding_get(cls, suffix: int):
        print("Serial接收到的后缀:", suffix)
        return cls.get_table_model(suffix)

    # 获取表模型
    @classmethod
    def get_table_model(cls, suffix: int):
        # 获取表名
        table_name = cls.get_table_name(suffix)
        # 判断是否在缓存中
        if table_name in cls._table_model:
            return cls._table_model[table_name]

        # 定义元类, 定制模型初始化
        class MetaClass(models.base.ModelBase):

            def __new__(cls, name, bases, attrs):
                """
                :param cls: 指向当前的MetaClass类, 这个cls有着调用这个MetaClass类的类信息
                :param name: 类名
                :param bases: 基类继承的所有父类
                :param attrs: 基类的所有属性
                """
                if 0 <= suffix < 128:
                    name = name + "_%d" % suffix
                else:
                    name = name + "_%d" % (abs(hash(str(suffix))) % 128)
                return super().__new__(cls, name, bases, attrs)

        # 定义基类
        class NewSerial(Serial, metaclass=MetaClass):
            class Meta:
                db_table = table_name

        # 打入缓存
        cls._table_model[table_name] = NewSerial
        return NewSerial


class SerialCategory(models.Model):
    """
    序列号分类
    """
    # TODO rename to price
    single_price = models.IntegerField(verbose_name='激活码单价（分）')
    name = models.CharField(max_length=255, verbose_name='分类名')
    valid_days = models.IntegerField(verbose_name='激活码有效天数')

    class Meta:
        db_table = 'fe_serial_category'
        verbose_name = '激活码分类表'
        verbose_name_plural = '激活码分类表'
        managed = False


# @deprecated("license项目中用不到")
class SerialOperationLog(models.Model):
    """
    序列号操作日志
    记录对应的序列号操作的记录
    在license项目中用不到
    # TODO 检查数据模型，这个表没有主键
    """
    serial_id = models.BigIntegerField(verbose_name='激活码ID')
    serial_code = models.CharField(max_length=255, verbose_name='激活码')
    reseller_id = models.BigIntegerField(verbose_name='经销商 ID')
    reseller_name = models.CharField(max_length=255, verbose_name='经销商')
    customer_id = models.BigIntegerField(verbose_name='客户ID')
    customer_name = models.CharField(max_length=255, verbose_name='客户名称')
    device_id = models.BigIntegerField(verbose_name='设备ID')
    machine_code = models.CharField(max_length=255, verbose_name='机器码')
    type = models.IntegerField(verbose_name='类型 存枚举 例如 吊销、禁用')
    reason = models.CharField(max_length=255, verbose_name='原因')

    class Meta:
        db_table = 'fe_serial_operation_log'
        verbose_name = '激活码操作记录表'
        verbose_name_plural = '激活码操作记录表'
        managed = False

# @deprecated("license项目中用不到")
class SerialRevokeLog(models.Model):
    """
    # TODO 检查数据库模型，这个表没有主键
    """
    serial_id = models.BigIntegerField(verbose_name='序列号ID')
    serial_code = models.CharField(max_length=255, verbose_name='序列号')
    batch_id = models.BigIntegerField(verbose_name='批次 id')
    batch_name = models.CharField(max_length=255, verbose_name='所属批次')
    customer_id = models.BigIntegerField(verbose_name='客户 id')
    customer_name = models.CharField(max_length=255, verbose_name='客户名称')
    create_user_name = models.CharField(max_length=255, verbose_name='创建人名称')
    reason = models.CharField(max_length=255, verbose_name='吊销原因')

    class Meta:
        db_table = 'fe_serial_revoke_log'
        verbose_name = '序列号吊销记录表'
        verbose_name_plural = '序列号吊销记录表'


class SerialBatch(models.Model):
    """
    序列号批次

    生成序列号的流程是
    1）创建序列号批次
    2）通过序列号批次生成序列号，并插入数据库
    """
    name = models.CharField(max_length=255, verbose_name='名称', null=False)
    count = models.IntegerField(verbose_name='序列号数量', null=False)
    reseller_id = models.BigIntegerField(verbose_name='经销商 id')
    reseller_name = models.CharField(max_length=255, verbose_name='经销商名称')
    serial_category_id = models.BigIntegerField(verbose_name='激活码类 ID')
    serial_category_name = models.CharField(max_length=255, verbose_name='激活码类型名')
    serial_valid_days = models.IntegerField(verbose_name='激活码有效天数（冗余）')
    serial_single_price = models.IntegerField(verbose_name='激活码单价（分）')
    serial_single_real_price = models.IntegerField(verbose_name='激活码实付单价（分）')
    serial_total_real_amount = models.IntegerField(verbose_name='实际总金额（分）')
    serial_total_amount = models.IntegerField(verbose_name='总金额（分）')
    pay_status = models.IntegerField(verbose_name='支付状态')
    pay_time = models.DateTimeField(verbose_name='支付时间')
    pay_type = models.IntegerField(verbose_name='支付类型')
    order_status = models.IntegerField(verbose_name='订单状态')
    generate_status = models.IntegerField(verbose_name='序列号生成状态')
    generate_time = models.DateTimeField(verbose_name='生成时间')
    create_user_name = models.CharField(max_length=255, verbose_name='创建人名称')
    serial_file_url = models.CharField(max_length=255, verbose_name='序列号 excel 文件网址')
    pay_order_id = models.BigIntegerField(verbose_name='订单 id')
    pay_order_no = models.CharField(max_length=255, verbose_name='订单号')
    is_deleted = models.IntegerField(blank=True, null=True, verbose_name="删除标识")

    class Meta:
        db_table = 'fe_serial_batch'
        verbose_name = '序列号批次表'
        verbose_name_plural = '序列号批次表'
        managed = False
